languages = {
    {
        {
            "c", "c++", "cpp", "cxx", "cc",
            "h", "h++", "hpp", "hxx",
        },
        "ytags_cpp",
    },

    {
        {
            "el",
        },
        "ytags_el",
    },

    {
        {
            "lua",
        },
        "ytags_lua"
    },

    {
        {
            "py",
        },
        "ytags_py"
    },
}

function predicate_by_suffix(suffix)
    for _, lang in pairs(languages) do
        local suffixs = lang[1]
        local app     = lang[2]
        for _, s in pairs(suffixs) do
            if s == suffix then
                return app
            end
        end
    end

    return ""
end

function predicate_by_content(filename)
    local fp = io.open(filename, "r")

    if not fp then return "" end

    local line = fp:read("*l")

    fp:close()

    if line then
        local b, e
        b = string.find(line, "-*-", 1, true)
        if b then
            b = b + 3
            e = string.find(line, "-*-", b, true)
            if e then
                e = e - 1
                if b <= e then
                    local tmp = string.sub(line, b, e)

                    tmp = string.lower(tmp)
                    local _, _, str =
                        string.find(tmp, "mode[ \t]*:[ \t]*([^; \t]+)[ \t]*;?")

                    if not str then
                        str = tmp
                    end

                    return predicate_by_suffix(str)
                end
            end
        end
    end

    return ""
end

-- ytags call this function when
-- it found a regular file, and the script
-- function return the application name
-- to handle the type of file.
-- when return empty string "" mean ignore the file
function main(filename)
    local pos, tmp

    while true do
        local i
        if pos then
            i = pos + 1
        else
            i = 1
        end
        tmp = string.find(filename, "/", i, true)
        if tmp then
            pos = tmp
        else
            break
        end
    end

    local filename_cut_path
    if pos then
        filename_cut_path = string.sub(filename,
                                       pos + 1, string.len(filename))
    else
        filename_cut_path = filename
    end

    pos = string.find(filename_cut_path, ".", 1, true)

    local suffix

    if pos then
        if pos + 1 <= string.len(filename_cut_path) then
            suffix = string.sub(filename_cut_path,
                                pos + 1,
                                string.len(filename_cut_path))
        end
    end

    if suffix then
        suffix = string.lower(suffix)
        return predicate_by_suffix(suffix)
    else
        return predicate_by_content(filename)
    end
end